<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>粒子特效</title>
</head>

<body>
    <canvas id="c1" style="background-color: #000;"></canvas>
    <script>
        /** @type {HTMLCanvasElement} */

        //画笔
        const c1 = document.querySelector('#c1');
        const { clientWidth: width, clientHeight: height } = document.documentElement
        c1.width = width;
        c1.height = height;
        window.onresize = function(){
            const { clientWidth: width, clientHeight: height } = document.documentElement
            c1.width = width;
            c1.height = height;
        }
        const ctx = c1.getContext('2d');

        //鼠标
        var mouse = {x:null,y:null,max:20000}
        window.onmousemove =function(e){
            mouse.x = e.clientX;
            mouse.y = e.clientY;
        }
        window.onmouseout =function(e){
            mouse.x = null
            mouse.y = null
        }


        //粒子
        //1.粒子创建
        var dots =[];
        for(var i=0;i<300;i++){
            var x = Math.random() * c1.width;
            var y = Math.random() * c1.height;
            var xa = Math.random() - 0.5;
            var ya = Math.random() - 0.5;
            var dot = {x,y,xa,ya,max:6000}
            dots.push(dot);
            //console.log(dots);

        }
        
        

        //粒子连线
        function animation(){
            //1.清空画布
            ctx.clearRect(0,0,c1.width,c1.height);
            //2.鼠标和数组结合
            var ndots = [mouse].concat(dots);
            //3.改变粒子水平垂直坐标
            dots.forEach(function(dot){
                dot.x += dot.xa;
                dot.y += dot.ya;
                dot.xa *= (dot.x>c1.width || dot.x<0)?-1:1;
                dot.ya *= (dot.y>c1.height || dot.y<0)?-1:1;
                //4.绘制粒子
                //console.log(dot)
                ctx.fillStyle = '#999999'
                ctx.fillRect(dot.x,dot.y,1,1);
                //5.连线
                for(var i=0;i<ndots.length;i++){
                    var d = ndots[i];
                    //判断是否是遍历出来的同一个粒子
                    if(d==dot)continue;
                    //开始两个粒子距离
                    var dx = dot.x - d.x;
                    var dy = dot.y - d.y;
                    var dxy = dx*dx+dy*dy;
                    if(dxy<d.max){
                        if(d == mouse && dxy > d.max/2  ){
                            dot.x -= dx*0.02;
                            dot.y -= dy*0.02;
                        }

                        ctx.beginPath();
                        ctx.lineWidth=0.3;
                        ctx.strokeStyle = '#999999';//'aqua'
                        ctx.moveTo(dot.x,dot.y);
                        ctx.lineTo(d.x,d.y);
                        ctx.stroke();
                        ctx.closePath();
                    }
                }
                ndots.splice(ndots.indexOf(dot),1);
            })
            requestAnimationFrame(animation);
        }

        animation();
    </script>
</body>

</html>